package com.fits.jwt;

import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.LinearLayoutCompat;
import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.google.gson.Gson;
import com.ydt.toolsdk.CYudp;
import com.ydt.toolsdk.IZfyControl;
import com.ydt.toolsdk.IZfyParams;
import com.ydt.toolsdk.ZfyParameters;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.LongUnaryOperator;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.videolan.libvlc.IVLCVout;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;

@CapacitorPlugin(name = "jwtPlugin")
public class jwtPluginPlugin extends Plugin implements IVLCVout.Callback {

    private jwtPlugin implementation = new jwtPlugin();

    private Map<Integer, PluginCall> pluginCallList;

    private ZfyParameters zfyParameters = null;
    /**
     * FTP连接.
     */
    private FTPClient ftpClient;

    public static final String PICTURE = "/PICTURE";

    public static final String VIDEO = "/MP4";
    // FTP 连接的事件
    public final int FTP_CONNECT = 10050;
    // FTP 查询文件的事件
    public final int FTP_LIST_FILES = 10051;
    // FTP 取回文件的事件
    public final int FTP_RETRIEVE_FILE = 10052;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private DisplayMetrics displayMetrics;

    private int DisplayHeight;
    private int DisplayWidth;

    private int mVideoWidth;
    private int mVideoHeight;
    private boolean isStop;

    @Override
    public void load() {
        pluginCallList = new HashMap<>();

        displayMetrics = getContext().getResources().getDisplayMetrics();
        DisplayHeight = displayMetrics.heightPixels;
        DisplayWidth = displayMetrics.widthPixels;

        CYudp.getInstance().setApiSecret("7294bf3b043b8d6e3e02f49b6492f0d4");
        CYudp
            .getInstance()
            .addCallbackInteface(
                new IZfyControl() {
                    @Override
                    public void onControl(int type, boolean ret, int state, String value) {
                        Log.i("===", "type: " + type + ", ret: " + ret + ", state: " + state + ", value: " + value);
                        if (type == IZfyControl.MSG_LOGIN) {
                            if (pluginCallList.containsKey(IZfyControl.MSG_LOGIN)) {
                                PluginCall call = pluginCallList.get(IZfyControl.MSG_LOGIN);
                                JSObject data = initResolveData(true, "登录成功");
                                data.put("ret", ret);
                                data.put("value", value == null ? "MSG_LOGIN" : value);
                                call.resolve(data);
                                pluginCallList.remove(IZfyControl.MSG_LOGIN);
                            }
                        } else if (type == IZfyControl.MSG_SET_PARAMETERS) {
                            if (pluginCallList.containsKey(IZfyControl.MSG_SET_PARAMETERS)) {
                                PluginCall call = pluginCallList.get(IZfyControl.MSG_SET_PARAMETERS);
                                JSObject data = initResolveData(true, "参数设置成功");
                                data.put("ret", ret);
                                data.put("value", value == null ? "MSG_SET_PARAMETERS" : value);
                                call.resolve(data);
                                pluginCallList.remove(IZfyControl.MSG_SET_PARAMETERS);
                            }
                        } else if (type == IZfyControl.MSG_REC) {
                            if (pluginCallList.containsKey(IZfyControl.MSG_REC)) {
                                PluginCall call = pluginCallList.get(IZfyControl.MSG_REC);
                                JSObject data = initResolveData(true, "录像" + (state == 1 ? "开始" : "停止"));
                                data.put("ret", ret);
                                data.put("value", value == null ? "MSG_REC" : value);
                                call.resolve(data);
                                pluginCallList.remove(IZfyControl.MSG_REC);
                            }
                        } else if (type == IZfyControl.MSG_PIC) {
                            if (pluginCallList.containsKey(IZfyControl.MSG_PIC)) {
                                PluginCall call = pluginCallList.get(IZfyControl.MSG_PIC);
                                JSObject data = initResolveData(true, "拍照成功");
                                data.put("ret", ret);
                                data.put("value", value == null ? "MSG_PIC" : value);
                                Log.i("===", "data =:" + data.toString());
                                call.resolve(data);
                                pluginCallList.remove(IZfyControl.MSG_PIC);
                            }
                        } else if (type == IZfyControl.MSG_AUDIO) {
                            String str = "操作成功";
                            if (!ret) {
                                str = "操作失败";
                            }
                            final String tip = str;
                        }
                    }
                }
            );
    }

    @PluginMethod
    public void connect(PluginCall call) {
        pluginCallList.put(IZfyControl.MSG_LOGIN, call);
        CYudp.getInstance().start(getContext());
        CYudp
            .getInstance()
            .setOnParamsListener(
                new IZfyParams() {
                    @Override
                    public void parameters(ZfyParameters zfyParames) {
                        zfyParameters = zfyParames;
                        String params = new Gson().toJson(zfyParames);
                        // 创建要发送给前端的数据
                        JSObject data = new JSObject();
                        data.put("zfyParameters", params);
                        // 发送数据给前端
                        notifyListeners("onParamsListener", data, true);
                        ftpConnect(null);
                    }

                    @Override
                    public void setParameterRet(int i) {}
                }
            );
    }

    @PluginMethod
    public void stopConnecting(PluginCall call) {
        //        pluginCallList.put(IZfyControl.MSG_LOGIN, call);
        CYudp.getInstance().stop();
        //        CYudp.getInstance().start(getContext());
    }

    @PluginMethod
    public void snap(PluginCall call) {
        pluginCallList.put(IZfyControl.MSG_PIC, call);
        CYudp.getInstance().sendCmd(IZfyControl.MSG_PIC, true, null);
    }

    @PluginMethod
    public void record(PluginCall call) {
        boolean starting = call.getBoolean("starting");
        pluginCallList.put(IZfyControl.MSG_REC, call);
        CYudp.getInstance().sendCmd(IZfyControl.MSG_REC, starting, null);
    }

    @PluginMethod
    public void setParameters(PluginCall call) {
        String params = call.getString("params");
        pluginCallList.put(IZfyControl.MSG_SET_PARAMETERS, call);
        Log.i("===", "params =" + params);

        if (TextUtils.isEmpty(params)) {
            JSObject data = initResolveData(false, "设置的参数为空");
            call.resolve(data);
        }
        ZfyParameters zfyParameters = new Gson().fromJson(params, ZfyParameters.class);
        CYudp.getInstance().sendParameters(zfyParameters);
    }

    @PluginMethod
    public void ftpConnect(PluginCall call) {
        pluginCallList.put(FTP_CONNECT, call);
        FTPConnectTask downloadTask = new FTPConnectTask();
        downloadTask.execute();
    }

    @PluginMethod
    public void ftpListFiles(PluginCall call) {
        String type = call.getString("type");
        Log.i("===", "type =" + type);
        if (TextUtils.isEmpty(type)) {
            JSObject data = initResolveData(false, "类型参数为空");
            call.resolve(data);
        } else {
            pluginCallList.put(FTP_LIST_FILES, call);
            new FTPListFilesTask().execute(type);
        }
    }

    @PluginMethod
    public void ftpRetrieveFile(PluginCall call) {
        String fileName = call.getString("fileName");
        String ftpFilePath = call.getString("ftpFilePath");
        if (TextUtils.isEmpty(fileName)) {
            JSObject data = initResolveData(false, "保存的本地文件名为空");
            call.resolve(data);
        } else if (TextUtils.isEmpty(ftpFilePath)) {
            JSObject data = initResolveData(false, "FTP文件路径为空");
            call.resolve(data);
        } else {
            File file = null;
            try {
                if (ftpFilePath.contains(PICTURE)) {
                    file = new File(getPictureCachePath() + "/" + fileName);
                } else if (ftpFilePath.contains(VIDEO)) {
                    file = new File(getVideoCachePath() + "/" + fileName);
                } else {
                    file = new File(getFileCachePath() + "/" + fileName);
                }

                if (!file.exists()) {
                    Log.i("===", "文件创建是否成功" + file.getAbsolutePath());
                    // 创建文件所在目录及其父目录
                    if (file.getParentFile() != null) {
                        file.getParentFile().mkdirs();
                    }
                    boolean mkdirs = file.createNewFile();
                    Log.i("===", "文件创建是否成功" + mkdirs);

                    if (!mkdirs) {
                        JSObject data = initResolveData(false, "文件创建失败");
                        call.resolve(data);
                        return;
                    }
                }
                pluginCallList.put(FTP_RETRIEVE_FILE, call);
                new FTPDownloadTask(file, ftpFilePath).execute();
            } catch (IOException e) {
                e.printStackTrace();
                Log.i("===", "e =" + e.toString());
            }
        }
    }

    // TODO: handle this cleaner
    private void releasePlayer() {
        if (libvlc == null) return;
        mMediaPlayer.stop();
        final IVLCVout vout = mMediaPlayer.getVLCVout();
        vout.removeCallback(this);
        vout.detachViews();
        holder = null;
        libvlc.release();
        libvlc = null;

        mVideoWidth = 0;
        mVideoHeight = 0;
    }

    private Dialog mRTSPDialog;

    //    private MediaPlayer mediaPlayer;
    private LibVLC libvlc;
    private MediaPlayer mMediaPlayer = null;

    public void createPlayer(String media, SurfaceView surfaceView) {
        //        releasePlayer();
        try {
            // Create LibVLC
            // TODO: make this more robust, and sync with audio demo
            ArrayList<String> options = new ArrayList<String>();
            options.add("--aout=opensles");
            options.add("--file-caching=2000");
            options.add("--live-caching=5000");
            options.add("--audio-time-stretch"); // time stretching
            options.add("-vvv"); // verbosity
            options.add("--http-reconnect");
            options.add("--ts-standard=auto");
            options.add("--drop-late-frames");
            options.add("--skip-frames");
            options.add("--rtsp-tcp");
            options.add("--fullscreen");

            libvlc = new LibVLC(getContext(), options);

            // Create media player
            mMediaPlayer = new MediaPlayer(libvlc);
            mMediaPlayer.setEventListener(
                new MediaPlayer.EventListener() {
                    @Override
                    public void onEvent(MediaPlayer.Event event) {
                        //                    StreamActivity player = mOwner.get();
                        switch (event.type) {
                            case MediaPlayer.Event.EndReached:
                                Log.d("End", "MediaPlayerEndReached");
                                //                            player.releasePlayer();
                                break;
                            case MediaPlayer.Event.Playing:
                            case MediaPlayer.Event.Paused:
                            case MediaPlayer.Event.Stopped:
                            default:
                                break;
                        }
                    }
                }
            );

            // Set up video output
            final IVLCVout vout = mMediaPlayer.getVLCVout();
            //            vout.setWindowSize(DisplayWidth, DisplayHeight);
            Log.i("===", "DisplayWidth =" + DisplayWidth + " DisplayHeight =" + DisplayHeight);
            vout.setWindowSize(DisplayWidth, (int) (DisplayHeight * 0.4));
            vout.setVideoView(surfaceView);
            vout.addCallback(this);
            vout.attachViews();

            Uri uri = Uri.parse(media);
            Media m = new Media(libvlc, uri);
            m.setHWDecoderEnabled(true, false);
            m.addOption(":network-caching=150");
            m.addOption(":clock-jitter=0");
            m.addOption(":clock-synchro=0");
            mMediaPlayer.setMedia(m);
            mMediaPlayer.play();
            //            setSize(WindowManager.LayoutParams.MATCH_PARENT, (int) (displayMetrics.heightPixels * 0.8), surfaceView);

        } catch (Exception e) {
            Toast.makeText(getContext(), "Error creating player!", Toast.LENGTH_LONG).show();
        }
    }

    private void setSize(int width, int height, SurfaceView surfaceView) {
        mVideoWidth = width;
        mVideoHeight = height;
        if (mVideoWidth * mVideoHeight <= 1) return;

        if (holder == null || surfaceView == null) return;

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int w = displayMetrics.widthPixels;
        int h = displayMetrics.heightPixels;

        boolean isPortrait = getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
        if (w > h && isPortrait || w < h && !isPortrait) {
            int i = w;
            w = h;
            h = i;
        }

        float videoAR = (float) mVideoWidth / (float) mVideoHeight;
        float screenAR = (float) w / (float) h;

        if (screenAR < videoAR) h = (int) (w / videoAR); else w = (int) (h * videoAR);

        // force surface buffer size
        holder.setFixedSize(mVideoWidth, mVideoHeight);

        // set display size
        ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
        lp.width = w;
        lp.height = h;
        surfaceView.setLayoutParams(lp);
        surfaceView.invalidate();
    }

    // display surface
    private SurfaceHolder holder;

    @PluginMethod
    public void playRTSP(PluginCall call) {
        String rtspUrl = CYudp.getInstance().getRtspUri();
        Log.i("===", "rtspUrl =" + rtspUrl);
        //        Intent intent = new Intent(getActivity(), StreamActivity.class);
        //        intent.putExtra("link", rtspUrl);
        //        getActivity().startActivity(intent);
        if (rtspUrl.contains("rtsp://null:")) {
            JSObject data = initResolveData(false, "设备没连接，RTSP地址为空");
            call.resolve(data);
            return;
        }

        if (mRTSPDialog == null) {
            mRTSPDialog = new Dialog(getContext(), R.style.MyDialog);

            View view = View.inflate(getContext(), R.layout.dialog_rtsp, null);
            mRTSPDialog.setContentView(view);
            // 获取SurfaceView引用
            SurfaceView surfaceView = view.findViewById(R.id.surface_stub);

            holder = surfaceView.getHolder();

            holder.addCallback(
                new SurfaceHolder.Callback() {
                    @Override
                    public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
                        createPlayer(rtspUrl, surfaceView);
                    }

                    @Override
                    public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {}

                    @Override
                    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {}
                }
            );

            //            surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            //                @Override
            //                public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
            //                    Log.i("===", "surfaceCreated =" + surfaceHolder);
            //                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            //                        mediaPlayer.setSurface(surfaceView.getHolder().getSurface());
            //                    }
            ////            String rtspUrl = "rtsp://192.168.195.144:5554/live";
            //
            //                    try {
            //                        // 设置数据源
            //                        mediaPlayer.setDataSource(rtspUrl);
            //
            //                        // 设置SurfaceHolder
            //                        mediaPlayer.setDisplay(surfaceHolder);
            //
            //                        // 准备异步
            //                        mediaPlayer.prepareAsync();
            //                    } catch (IOException e) {
            //                        e.printStackTrace();
            //                    }
            //
            //                }
            //
            //                @Override
            //                public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
            //                    Log.i("===", "surfaceChanged =" + surfaceHolder);
            //                }
            //
            //                @Override
            //                public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
            //                    Log.i("===", "surfaceDestroyed =" + surfaceHolder);
            //                }
            //            });
            ////            SurfaceView surfaceView = new SurfaceView(getContext());
            //
            //            Log.i("===", "surfaceView =" + surfaceView);
            //            // 创建MediaPlayer实例
            //            mediaPlayer = new MediaPlayer();
            //            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            ////            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ) {
            ////                mediaPlayer.setSurface(surfaceView.getHolder().getSurface());
            ////            }
            //////            String rtspUrl = "rtsp://192.168.195.144:5554/live";
            ////
            ////            try {
            ////                // 设置数据源
            ////                mediaPlayer.setDataSource(rtspUrl);
            ////
            ////                // 设置SurfaceHolder
            ////                SurfaceHolder surfaceHolder = surfaceView.getHolder();
            ////                mediaPlayer.setDisplay(surfaceHolder);
            ////
            ////                // 准备异步
            ////                mediaPlayer.prepareAsync();
            ////            } catch (IOException e) {
            ////                e.printStackTrace();
            ////            }
            //
            //            // 设置监听器
            //            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            //                @Override
            //                public void onPrepared(MediaPlayer mp) {
            //                    // 准备完成，开始播放
            //                    mediaPlayer.start();
            //                }
            //            });
            //
            //            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            //                @Override
            //                public boolean onError(MediaPlayer mp, int what, int extra) {
            //                    // 处理播放错误
            //                    return false;
            //                }
            //            });

            mRTSPDialog.setCanceledOnTouchOutside(false);
            // 防止物理按键后退关闭了弹窗
            // mRTSPDialog.setCancelable(false);
            Window window = mRTSPDialog.getWindow();
            //设置弹出窗口大小
            window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, (int) (displayMetrics.heightPixels * 0.4));
            //            DisplayWidth = WindowManager.LayoutParams.MATCH_PARENT;
            //            DisplayHeight = (int) (displayMetrics.heightPixels * 0.4);
            //设置显示位置
            window.setGravity(Gravity.CENTER);

            //FLAG_NOT_TOUCH_MODAL作用：即使该window可获得焦点情况下，仍把该window之外的任何event发送到该window之后的其他window
            window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
            //FLAG_WATCH_OUTSIDE_TOUCH作用：如果点击事件发生在window之外，就会收到一个特殊的MotionEvent，为ACTION_OUTSIDE
            window.setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
            //blog.csdn.net/smileiam/article/details/90643667

            //设置动画效果
            // window.setWindowAnimations(R.style.ActionSheetDialogAnimation);
            window.setDimAmount(0);

            window
                .getDecorView()
                .setOnTouchListener(
                    new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            Log.i("===", "弹窗外点击");
                            // 在这里处理点击弹窗外的事件，不要关闭弹窗
                            return false;
                        }
                    }
                );

            mRTSPDialog.setOnDismissListener(
                new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        // 创建要发送给前端的数据
                        JSObject data = new JSObject();
                        // 发送数据给前端
                        if (!isStop) notifyListeners("onVideoDismiss", data, true);
                    }
                }
            );
        }
        isStop = false;
        mRTSPDialog.show();
    }

    @PluginMethod
    public void stopRTSP(PluginCall call) {
        Log.i("===", "stopRTSP =");
        //        Intent intent = new Intent(getActivity(), StreamActivity.class);
        //        intent.putExtra("link", rtspUrl);
        //        getActivity().startActivity(intent);

        releasePlayer();
        if (mRTSPDialog != null) {
            isStop = true;
            mRTSPDialog.dismiss();
        }
    }

    private String mExternalFilesDirsAbsolutePath = "";

    // 获取本地存储路径
    public String getExternalFilesDirs() {
        if (TextUtils.isEmpty(mExternalFilesDirsAbsolutePath)) {
            File externalFilesDir = new File(getContext().getExternalFilesDir(null) + "");
            mExternalFilesDirsAbsolutePath = externalFilesDir.getAbsolutePath();
        }

        return mExternalFilesDirsAbsolutePath;
    }

    // 图片的保存地址
    public String getFileCachePath() {
        return getExternalFilesDirs() + "/fits/";
    }

    // 图片的保存地址
    public String getPictureCachePath() {
        return getExternalFilesDirs() + "/fits" + PICTURE + "/";
    }

    // 视频的保存地址
    public String getVideoCachePath() {
        return getExternalFilesDirs() + "/fits" + VIDEO + "/";
    }

    public JSObject initResolveData(boolean isSuccess, String message) {
        JSObject data = new JSObject();
        data.put("isSuccess", isSuccess);
        data.put("message", message);
        return data;
    }

    @Override
    public void onSurfacesCreated(IVLCVout vlcVout) {}

    @Override
    public void onSurfacesDestroyed(IVLCVout vlcVout) {}

    public static class FTPFileModule {

        public String FileName = "";

        public long FileSize = 0;

        public String Times = "";

        public String FtpFilePath = "";

        public FTPFileModule(String fileName, long fileSize, String times, String ftpFilePath) {
            FileName = fileName;
            FileSize = fileSize;
            Times = times;
            FtpFilePath = ftpFilePath;
        }
    }

    public class FTPConnectTask extends AsyncTask<Void, Void, Void> {

        public FTPConnectTask() {}

        @Override
        protected Void doInBackground(Void... voids) {
            Log.i("===", "doInBackgroundX");
            try {
                openConnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    public void openConnect() throws IOException {
        Log.i("===", "openConnect ");
        this.ftpClient = new FTPClient();
        int reply;

        ftpClient.setControlEncoding("UTF-8");
        ftpClient.connect(CYudp.getInstance().getAPiP(), 2221);
        // 获取响应值
        reply = ftpClient.getReplyCode();
        Log.i("===", "连接 =" + reply);
        if (!FTPReply.isPositiveCompletion(reply)) {
            // 断开连接
            ftpClient.disconnect();
            throw new IOException("connect fail: " + reply);
        }
        // 登录到服务
        ftpClient.login("ftp", "ftp");
        // 获取响应值
        reply = ftpClient.getReplyCode();
        Log.i("===", "登录 =" + reply);
        if (!FTPReply.isPositiveCompletion(reply)) {
            // 断开连接
            ftpClient.disconnect();

            if (pluginCallList.containsKey(FTP_CONNECT)) {
                PluginCall call = pluginCallList.get(FTP_CONNECT);
                JSObject data = initResolveData(false, "FTP连接异常");
                call.resolve(data);
                pluginCallList.remove(FTP_CONNECT);
            }

            throw new IOException("connect fail: " + reply);
        } else {
            // 获取登录信息
            FTPClientConfig config = new FTPClientConfig(ftpClient.getSystemType().split(" ")[0]);
            config.setServerLanguageCode("zh");
            ftpClient.configure(config);
            // 使用被动模式设为默认
            ftpClient.enterLocalPassiveMode();
            // 二进制文件支持
            ftpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
            System.out.println("login");

            if (pluginCallList.containsKey(FTP_CONNECT)) {
                PluginCall call = pluginCallList.get(FTP_CONNECT);
                JSObject data = initResolveData(true, "登录成功");
                if (call != null) call.resolve(data);
                pluginCallList.remove(FTP_CONNECT);
            }
        }
    }

    public class FTPListFilesTask extends AsyncTask<String, Void, Void> {

        public FTPListFilesTask() {}

        @Override
        protected Void doInBackground(String... params) {
            Log.i("===", "params =" + params[0]);
            if (ftpClient == null) return null;
            try {
                FTPFile[] ftpFiles = ftpClient.listFiles(params[0]);

                ArrayList<FTPFileModule> ftpFileModules = new ArrayList<>();

                for (FTPFile ftpFile : ftpFiles) {
                    Log.i("===", "文件 =" + ftpFile.toFormattedString() + " 名字 =" + ftpFile.getName());
                    FTPFileModule ftpFileModule = new FTPFileModule(
                        ftpFile.getName(),
                        ftpFile.getSize(),
                        simpleDateFormat.format(ftpFile.getTimestamp().getTime()),
                        params[0] + "/" + ftpFile.getName()
                    );

                    ftpFileModules.add(ftpFileModule);
                }

                String s = new Gson().toJson(ftpFileModules);
                Log.i("===", "s =" + s);

                if (pluginCallList.containsKey(FTP_LIST_FILES)) {
                    PluginCall call = pluginCallList.get(FTP_LIST_FILES);
                    JSObject data = initResolveData(true, "文件获取成功");
                    data.put("data", new Gson().toJson(ftpFileModules));
                    call.resolve(data);
                    pluginCallList.remove(FTP_LIST_FILES);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    private boolean downloadFile(File localFile, String ftpFilePath) throws IOException {
        Log.i("===", "ftpFilePath =" + ftpFilePath);
        Log.i("===", "下载的文件 =" + localFile.getAbsolutePath());
        boolean flag = true;
        // 创建输出流
        OutputStream outputStream = new FileOutputStream(localFile);
        // 统计流量
        //        response += ftpFile.getSize();
        // 下载单个文件
        flag = ftpClient.retrieveFile(ftpFilePath, outputStream);
        // 关闭文件流
        outputStream.close();

        if (pluginCallList.containsKey(FTP_RETRIEVE_FILE)) {
            PluginCall call = pluginCallList.get(FTP_RETRIEVE_FILE);
            JSObject data = initResolveData(true, "文件下载成功");
            data.put("localFilePath", localFile.getAbsolutePath());
            call.resolve(data);
            pluginCallList.remove(FTP_RETRIEVE_FILE);
        }

        return flag;
    }

    public class FTPDownloadTask extends AsyncTask<Void, Void, Void> {

        private File file;

        private String ftpFilePath;

        public FTPDownloadTask(File file, String ftpFilePath) {
            this.file = file;
            this.ftpFilePath = ftpFilePath;
        }

        @Override
        protected Void doInBackground(Void... voids) {
            try {
                downloadFile(file, ftpFilePath);
            } catch (IOException e) {
                e.printStackTrace();
                Log.i("===", "e =" + e.toString());
            }
            return null;
        }
    }
}
